import coin.proto.coin_market_enums_pb2 as coin_enum
from coin.exchange.base.order_gateway_log_builder import (prepare_builder,
                                                          to_proto_order_side,
                                                          BaseOrderEventBuilder)
from coin.exchange.base.order_gateway_logger import OrderGatewayLogProvider
from coin.proto.coin_order_gateway_pb2 import OrderEvent
import coin.proto.coin_order_enums_pb2 as coin_order


class OrderEventBuilder(BaseOrderEventBuilder):
  def set_order(self, order):
    internal_order_id = order.order_id
    external_order_id = order.internal.exchange_order_id
    order_price = order.price
    order_qty = order.qty
    order_side = to_proto_order_side(order.order_side)
    order_type = coin_order.DAY_LIMIT_ORDER

    self.oe.MergeFrom(
        OrderEvent(internal_order_id=internal_order_id,
                   external_order_id=str(external_order_id),
                   order_price=order_price,
                   order_qty=order_qty,
                   order_side=order_side,
                   order_type=order_type))


class OkexOrderGatewayLogProvider(OrderGatewayLogProvider):
  exchange_type = coin_enum.Okex

  def gen_order_event_and_log(self, order, timestamp, order_event_type):
    builder = prepare_builder(OrderEventBuilder,
                              None,
                              timestamp,
                              self.get_next_order_event_id(),
                              self.exchange_type,
                              order.product.symbol)
    builder.set_order(order)

    if order_event_type == OrderEvent.ORDER_ACCEPTED:
      order_state = coin_order.WORKING_ORDER
    elif order_event_type == OrderEvent.ORDER_FILLED:
      if order.internal.fill.fully_filled:
        order_state = coin_order.DEAD_ORDER
      else:
        order_state = coin_order.WORKING_ORDER
      builder.set_fill(order.internal.fill.value.price_last_fill,
                       order.internal.fill.value.qty_last_fill)
    elif order_event_type == OrderEvent.CANCEL_ACCEPTED:
      order_state = coin_order.WORKING_ORDER
    elif order_event_type == OrderEvent.CANCEL_CONFIRMED:
      order_state = coin_order.DEAD_ORDER
    else:
      raise NotImplementedError()

    builder.set_state(order_event_type=order_event_type,
                      order_state=order_state,
                      order_event_source=OrderEvent.EXCHANGE)
    self.write_order_event(builder.oe)
